package SharedDrawing;
import common.Md5;
import common.XmlConstants;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;

/*
 * This file is part of shared-drawing.
 * shared-drawing is free software: you can redistribute it and/or modify it 
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option )
 * any later version. shared-drawing is distributed in the hope that it will
 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 * You should have received a copy of the GNU General Public License along with 
 * shared-drawing. If not, seehttp://www.gnu.org/licenses/.
 */

public class ConnexionManager {
    private String userId;
    private String nickname;
    private String workgroupName;
    private String workgroupPassword;
    private HashMap<String, String> userList;
    private SharedDrawingUI.UIWorker worker;
    private boolean connected;
    
    private static ConnexionManager instance;
    /**
     * default constructor
     */
    private ConnexionManager()
    {
        userId = "0";
        nickname = "me";
        userList = new HashMap<String, String>();
        worker = SharedDrawingUI.getInstance().getWorker();
    }
    
    /**
     * to get the only instance since this class is a singleton
     */
    public static ConnexionManager getInstance()
    {
        if(instance == null)
            instance = new ConnexionManager();
        
        return instance;
    }
    
    /**
     * This method is used to connect on a workgroup
     * @throws NoSuchAlgorithmException the given hash method doesnt exist
     * @throws UnsupportedEncodingException encoding problem
     */
    public void 
    join(String workgroup, String password)
    throws NoSuchAlgorithmException, UnsupportedEncodingException
    {
        workgroupName = workgroup;
        workgroupPassword = password;
        Action attr = new Action(XmlConstants.joinWorkgroup);
        attr.addContent(XmlConstants.emitterNickName, nickname);
        attr.addContent(XmlConstants.workgroupName, workgroupName);
        attr.addContent(XmlConstants.workgroupPassword,new Md5().toMd5(workgroupPassword));
        XmlGenerator.sendXml(attr);
    }
    
    /**
    * When we connect on the server, the server gives an id
    * @param Id the id given by the server
    */
    public void welcome(String Id)
    {
        userId = Id;
        userList.clear();
        userList.put(Id, nickname);
        worker.push(new Action(XmlConstants.welcome));
        connected = true;
    }
    
    /**
     * This method is used to leave from a workgroup
     */
    public void leave()
    {
        userId = "0";
        userList.clear();
        Pages.getInstance().clear();
        Action action = new Action(XmlConstants.leaveWorkgroup);
        XmlGenerator.sendXml(action);
        connected = false;
        SharedDrawingUI.getInstance().jListUsersListClear();
    }
    
   /**
    * The server told me i left the server
    */
    public void goodBye()
    {
        System.out.println(
                "receiving a goodbye but I should have been disconnected");
    }
    
    /**
     * someone has joined the workgroup
     * @param id the id of the new user
     * @param nickName the nickname of the new user
     */
    public void someoneJoin(String id, String nickName)
    {
        
        userList.put(id, nickName);
        Action action = new Action(XmlConstants.joinWorkgroup);
                    action.addContent(XmlConstants.emitterNickName, nickName);
        worker.push(action);
    }
    
    /**
     * someone has left the workgroup
     * @param id the id of the user who left
     */
    public void someoneLeave(String id)
    {
        String nick = userList.get(id);
        userList.remove(id);
        for(Page page : Pages.getInstance().getPages().values())
        {
            page.decPageView(nick);
        }
        Action action = new Action(XmlConstants.leaveWorkgroup);
                    action.addContent(
                            XmlConstants.emitterNickName, nick);
        worker.push(action);
    }    

    /**
     * to connect on the server
     * @return a boolean which values true if connexion was successful. false if connexion failed.
     */
    public boolean connect(String nickName, String host, int port){ // appel à la socket ici
        
        boolean isConnected = SocketClient.connect(host, port);
        if(isConnected == true)
        {
            nickname = nickName;
            SocketClient.getInstance().start();
        }
        return isConnected;
    }
    
    /**
     * 
     * @param drawingName
     * @param xmlDrawing 
     */
    public void openPage(int index)
    {
        // on fait apparaître l'onglet associé à l'index
        // on fait incPageView
        // on envoie un message openPage au serveur
    }
    
    /**
     * 
     * @param index 
     */
    public void closePage(int index)
    {
        // on fait juste un hide du tab associé a l'index
        // on décrémente
    }
    
    public void newPage(String title)
    {
        SharedDrawingUI.getInstance().DrawPage(title);
    }
    
    /**
     * @return the nickname of the current user
     */
    public String getNickname() {
        return nickname;
    }

    /**
     * to get the nickname of a user by providing his identifier
     * @param id the user's identifier
     * @return a String which is the nickname of the user. Or null if the user doesn't exist.
     */
    public String getNickName(String id)
    {
        return(userList.get(id));
    }
    
    /**
     * used to set the nickname chosen by the user
     * @param nickname the chosen nickname
     */
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    
    /**
     * to get the server address
     * @return the server address 
     */
    public String getHost() {
        return (SocketClient.getInstance().getHost());
    }

    /**
     * to get the current listening port
     * @return the listening port
     */
    public int getPort() {
        return SocketClient.getInstance().getPort();
    }
    
    /**
     * to get the user id (the user who is launching the client occurence)
     */
    public String getUserId()
    {
        return userId;
    }

    public HashMap<String, String> getUserList() {
        return userList;
    }

    /**
     * to get the name of the workgroup we are working on.
     * @return the name of the current workgroup
     */
    public String getWorkgroupName() {
        return workgroupName;
    }

    /**
     * to get the clear password of the current workgroup.
     * @return the clear password
     */
    public String getWorkgroupPassword() {
        return workgroupPassword;
    }

    /**
     * to set the name of the workgroup we are trying to join.
     * @param workgroupName the name of the workgroup. It might be invalid since it is a user input.
     */
    public void setWorkgroupName(String workgroupName) {
        this.workgroupName = workgroupName;
    }

    /**
     * to set the clear password of the workgroup we are trying to join.
     * @param workgroupPassword the clear password of the workgroup. It might be incorrect since it is a user input.
     */
    public void setWorkgroupPassword(String workgroupPassword) {
        this.workgroupPassword = workgroupPassword;
    }

    boolean isMe(String nickname) {
        if(this.nickname.equals(nickname))
        {
            return true;
        }
        return false;
    }

    public boolean isConnected() {
        return connected;
    }

    void disconnect() {
        SocketClient socket = SocketClient.getInstance();
        if(socket != null)
        {
            socket.disconnect();
        }
    }
        
}